﻿using System;
using System.Xml;
using NJabber.Properties;

namespace NJabber.Stream.Elements
{
    public abstract class ErrorElement : XmppStreamElement
    {
        private string errorName;
        private string errorInfoNamespace;
        private string errorDescription;
        private XmppStreamElement errorDetails;

        public ErrorElement(string errorInfoNamespace) : this(errorInfoNamespace, "")
        {
        }

        public ErrorElement(string errorInfoNamespace, string namespaceUri) : this(errorInfoNamespace, namespaceUri, "")
        {
        }

        public ErrorElement(string errorInfoNamespace, string namespaceName, string namespaceUri) : base("error", namespaceName, namespaceUri)
        {
            this.errorInfoNamespace = errorInfoNamespace;
        }

        public string ErrorName
        {
            get { return errorName; }
            set { errorName = value; }
        }

        public string ErrorInfoNamespace
        {
            get { return errorInfoNamespace; }
        }

        public string ErrorDescription
        {
            get { return errorDescription; }
            set { errorDescription = value; }
        }

        public string DescriptionLang { get; set; }

        public XmppStreamElement ErrorDetails
        {
            get { return errorDetails; }
            set
            {
                if (value != null && value.Namespace.IsEmpty) throw new ArgumentException(Resources.ErrorDetailsWithoutNamespaceExceptionMessage);
                errorDetails = value;
            }
        }

        protected override void WritePayload(XmlWriter writer)
        {
            base.WritePayload(writer);
            WriteErrorName(writer);
            WriteErrorDescription(writer);
            WriteErrorDetails(writer);
        }

        private void WriteErrorName(XmlWriter writer)
        {
            if (!string.IsNullOrEmpty(ErrorName)) writer.WriteElementString(ErrorName, errorInfoNamespace, null);
        }

        private void WriteErrorDescription(XmlWriter writer)
        {
            if (string.IsNullOrEmpty(errorDescription)) return;
            writer.WriteStartElement("text", errorInfoNamespace);
            if (!string.IsNullOrEmpty(ErrorDescription)) writer.WriteAttributeString("xml", "lang", null, DescriptionLang);
            writer.WriteString(errorDescription);
            writer.WriteEndElement();
        }

        private void WriteErrorDetails(XmlWriter writer)
        {
            if (errorDetails != null) errorDetails.Write(writer);
        }

        public override bool Equals(object obj)
        {
            ErrorElement element = obj as ErrorElement;
            if (element == null) return false;
            return Equals(element);
        }

        public bool Equals(ErrorElement element)
        {
            return base.Equals(element) 
                && AreValuesEquals(ErrorName, element.ErrorName) 
                && AreValuesEquals(ErrorDescription, element.ErrorDescription)
                && AreValuesEquals(DescriptionLang, element.DescriptionLang);
        }
    }
}
